#include "rpilot.h"
#include "bind.h"
#include <string.h>

char *filebase( char *filename )
{
  int dotpos, i;

  dotpos = -1;
  for( i=strlen(filename)-1; i>=0; i-- ) {
    if( filename[i] == '.' ) {
      dotpos = i;
      break;
    }
  }

  if( dotpos == -1 ) {
    return filename;
  } else { 
    return new_string_from( filename, 0, dotpos );
  }    
}

void bindfile( char *filename, char *outfile, char *dataname, char *funcname, 
	       int mainfunc )
{
  FILE *header, *source;
  char *base, *hfile, *srcfile;
  line *curr;
  char *buffer;
  int i;

  if( outfile == NULL ) {
    base = filebase( filename );
  } else {
    base = outfile;
  }


  hfile = (char *)malloc(strlen(base)+3);
  strcpy( hfile, base );
  strcat( hfile, ".h" );
  srcfile = (char *)malloc(strlen(base)+3);
  strcpy( srcfile, base );
  strcat( srcfile, ".c" );

  if( (header = fopen(hfile, "w")) == NULL ) {
    err( ERR_FILE, hfile );
  }
  if( (source = fopen(srcfile, "w")) == NULL ) {
    err( ERR_FILE, srcfile );
  }

  if( dataname == NULL ) {
    dataname = new_string( "pilot_data" );
  }
  if( funcname == NULL ) {
    funcname = new_string( "run_pilot" );
  }
    

  init();
  readfile( filename );

  
  // start outputting to files

  fprintf( header, "/* PILOT code datafile - generated by RPilot %s */\n\n",
	   VERSION );
  fprintf( header, "#ifndef _%s_h_\n#define _%s_h_\n\n", base, base );
  fprintf( header, "#include <stdio.h>\n\n" );

  fprintf( header, "void %s(void);\n", funcname );
  fprintf( header, "\n\n#endif" );
  
  fclose( header );

  
  fprintf( source, "/* PILOT code source file - generated by RPilot %s */\n\n",
	   VERSION );
  fprintf( source, "#include \"%s\"\n\n", hfile );
  fprintf( source, "extern void run_bound( char *code[] );\n\n" );
  fprintf( source, "void %s(void)\n{\n", funcname );

  fprintf( source, "char *%s[] = {\n", dataname );
  
  curr = (line *)rpi->linehead;
  curr = (line *)curr->next;  // first entry is always blank, so skip it

  while( curr != NULL ) {

    print_line( curr );
    printf( "\n" );

    buffer = get_line( curr );
    fprintf( source, "\"" );
    for( i = 0; i<strlen(buffer); i++ ) {
      switch( buffer[i] ) {
      case '\"' : 
	fprintf( source, "\\\"" );
	break;
      case '\'' :
	fprintf( source, "\\\'" );
	break;
      case '\\' : 
	fprintf( source, "\\\\" );
	break;
      default:
	fprintf( source, "%c",  buffer[i] );
	break;
      }
    }
    fprintf( source, "\",\n" );
    free( buffer );
    //    fprintf( source, "  \"" );
    //    print_line_to( curr, source );
    //    fprintf( source, "\",\n" );
    curr = (line *)curr->next;
  }
    
  fprintf( source, "NULL\n};\n\n" );

  fprintf( source, "run_bound( %s );\n}\n\n", dataname );
  
  if( mainfunc == TRUE ) {
    fprintf( source, "int main( int argc, char *argv[] )\n{\n" );
    fprintf( source, "  %s();\n  return 0;\n}\n\n", funcname );
  }

  fclose( source );

}


// run some bound code
void run_bound( char *code[] )
{
  line *curr;
  int i = 0;

  init();
  rpi->filename = new_string( "<<Bound Code>>" );

  curr = (line *)rpi->linehead;
  
  while( code[i] != NULL ) {
    printf( "code[%d] is \"%s\"\n", i, code[i] );
    curr->next = (struct line *)new_line( code[i], '!', i+1 );
    curr = (line *)curr->next;
    i++;
  }

  curr = (line *)rpi->linehead;
  rpi->linehead = curr->next;
  interp();
}

